<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License. 
-->
<html>
<head>
    <link type="text/css" rel="stylesheet" href="https://struts.apache.org/css/default.css">
    <style type="text/css">
        .dp-highlighter {
            width:95% !important;
        }
    </style>
    <style type="text/css">
        .footer {
            background-image:      url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
            background-repeat:     repeat-x;
            background-position:   left top;
            padding-top:           4px;
            color:                 #666;
        }
    </style>
    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' rel='stylesheet' type='text/css' />
    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' rel='stylesheet' type='text/css' />
    <script src='https://struts.apache.org/highlighter/js/shCore.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' type='text/javascript'></script>
    <script type="text/javascript">
        SyntaxHighlighter.defaults['toolbar'] = false;
        SyntaxHighlighter.all();
    </script>
    <script type="text/javascript" language="javascript">
        var hide = null;
        var show = null;
        var children = null;

        function init() {
            /* Search form initialization */
            var form = document.forms['search'];
            if (form != null) {
                form.elements['domains'].value = location.hostname;
                form.elements['sitesearch'].value = location.hostname;
            }

            /* Children initialization */
            hide = document.getElementById('hide');
            show = document.getElementById('show');
            children = document.all != null ?
                    document.all['children'] :
                    document.getElementById('children');
            if (children != null) {
                children.style.display = 'none';
                show.style.display = 'inline';
                hide.style.display = 'none';
            }
        }

        function showChildren() {
            children.style.display = 'block';
            show.style.display = 'none';
            hide.style.display = 'inline';
        }

        function hideChildren() {
            children.style.display = 'none';
            show.style.display = 'inline';
            hide.style.display = 'none';
        }
    </script>
    <title>What is the ActionContext?</title>
</head>
<body onload="init()">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
    <tr class="topBar">
        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a href="faqs.html">FAQs</a>&nbsp;&gt;&nbsp;<a href="what-is-the-actioncontext.html">What is the ActionContext?</a>
        </td>
        <td align="right" valign="middle" nowrap>
            <form name="search" action="https://www.google.com/search" method="get">
                <input type="hidden" name="ie" value="UTF-8" />
                <input type="hidden" name="oe" value="UTF-8" />
                <input type="hidden" name="domains" value="" />
                <input type="hidden" name="sitesearch" value="" />
                <input type="text" name="q" maxlength="255" value="" />
                <input type="submit" name="btnG" value="Google Search" />
            </form>
        </td>
    </tr>
</table>

<div id="PageContent">
    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 2 Documentation</div>
        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">What is the ActionContext?</div>

        <div class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13994">
                <img src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Edit Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13994">Edit Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
                <img src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Browse Space"></a>
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse Space</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13994">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13994">Add Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13994">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add News"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13994">Add News</a>
        </div>
    </div>

    <div class="pagecontent">
        <div class="wiki-content">
            <div id="ConfluenceContent">

<p>A striking attribute of the framework is the brevity of its signatures. For example:</p>

<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> S1 Action </p></th><td colspan="1" rowspan="1" class="confluenceTd"> <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">ActionForward execute(ActionMapping, ActionForm, ServletRequest, ServletResponse)</pre>
</div></div></td></tr><tr><td></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> S2 Action </p></th><td colspan="1" rowspan="1" class="confluenceTd"> <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">String execute()</pre>
</div></div> </td></tr></tbody></table></div>


<p>How can this be? How can a key method take no arguments and yet perform useful work within an application?</p>

<p>To keep signatures brief, and methods useful, the framework uses two techniques: <em>Dependency Injection</em> and <em>Thread Local</em>, both of which, in turn, rely on the <em>ActionContext</em>. </p>

<h2 id="WhatistheActionContext?-DependencyInjection">Dependency Injection </h2>

<p>Many Interceptors are used to populate propertes on an Action. For example, the <a shape="rect" href="servlet-config-interceptor.html">Servlet Config Interceptor</a> can set Map properties representing the HTTP Request, Session, and Appplication objects. </p>

<p>Though, the signature for an Interceptor is nearly as brief as Action: </p>

<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">String intercept(ActionInvocation invocation)</pre>
</div></div>

<p>Looking through <a shape="rect" class="unresolved" href="#">ActionInvocation</a>, there are several interesting properties, but nothing that reveals the HTTP contexts. (Good thing! since it is a web-independant XWork class.)</p>

<p>So how does an Interceptor obtain the HTTP contexts to inject? </p>

<h2 id="WhatistheActionContext?-ThreadLocal">ThreadLocal </h2>

<p>The <a shape="rect" class="unresolved" href="#">ThreadLocal</a> class is not a new kid on the block. It's been available to developers since Java 1.2. In effect, each thread has its own copy of the variables on a ThreadLocal class. </p>

<p>The framework uses ThreadLocal in connection with the ActionContext class to make servlet configuration and other runtime details available. </p>

<h2 id="WhatistheActionContext?-ActionContext">ActionContext</h2>

<p>From <em>anywhere</em> within an Struts 2 application, you can obtain a reference to the <a shape="rect" class="unresolved" href="#">ActionContext</a> by calling  </p>

<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
ActionContext context = ActionContext.getContext();
</pre>
</div></div>

<p>For example, if a helper class is called from an Action, and if it happens to need access to ServletContext (maybe it is writing a file and needs ServletContext to get a path to it), the helper can obtain the ActionContext directly. Nothing needs to be passed from the Action.  </p>

<p>In frameworks like Struts 1, details like the runtime request and response are passed around like hot potatoes. In Struts 2, such details are bundled together in the ActionContext. In S1, Actions are bound to HTTP through the execute signature. In S2, Actions can be a plain old Java object, and each bound to HTTP only to the extent required. </p>

<p>Of course, the dark side of ThreadLocal is that it is easy to bind business logic classes to XWork. An otherwise pristine business class could grab request parameters directly from the ActionContext. The request parameters are exposed as a plain Map, so binding to HTTP is avoided, but the class still becomes bound to XWork. Of course, if you've decided to use XWork as your business logic framework, then binding to ActionContext might not be a problem. </p>

<p>The darker side is that classes that depend heavily on ThreadLocal can be diffcult to unit test. A cleaner design centralizes access to ThreadLocal variables, so that other classes are easier to test.</p>

<h2 id="WhatistheActionContext?-Backto">Back to <a shape="rect" class="createlink" href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=ds&amp;title=FAQs">FAQs</a></h2>

<hr>

<p>This material originally adopted from <a shape="rect" class="external-link" href="http://wiki.apache.org/struts/ActionContext?action=edit">http://wiki.apache.org/struts/ActionContext?action=edit</a>.</p></div>
        </div>

        
    </div>
</div>
<div class="footer">
    Generated by CXF SiteExporter
</div>
</body>
</html>
